package com.gin.kotlin.no_gay_alliance.fragment.post

import android.app.Activity
import android.content.Intent
import android.os.Bundle
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.ActivityResultLauncher
import com.gin.kotlin.no_gay_alliance.adapter.post.UploadBodyAdapter
import com.gin.kotlin.no_gay_alliance.app.App
import com.gin.kotlin.no_gay_alliance.argument.UploadArgument
import com.gin.kotlin.no_gay_alliance.base.AbstractBindingFragment
import com.gin.kotlin.no_gay_alliance.base.AlertDialogUtils
import com.gin.kotlin.no_gay_alliance.base.ContentFile
import com.gin.kotlin.no_gay_alliance.databinding.FragmentPostAttachmentUploadBinding
import com.gin.kotlin.no_gay_alliance.utils.TimeUtils
import com.gin.nga.response.post.UploadBody
import com.gin.nga.utils.UploadBodyBuilder
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.io.File
import java.time.ZonedDateTime
import java.util.UUID

/**
 * 文件上传
 * @property uploadArgument 上传参数
 * @property contentFiles 被选择上传的文件信息列表,包含uri
 * @property launcher 启动器
 * @property adapter 适配器
 * @property tempDir 待上传附件临时目录
 */
class PostAttachmentUploadFragment : AbstractBindingFragment<FragmentPostAttachmentUploadBinding>(), ActivityResultCallback<ActivityResult> {
    private lateinit var uploadArgument: UploadArgument
    private lateinit var contentFiles: MutableList<ContentFile>
    private lateinit var launcher: ActivityResultLauncher<Intent>
    private lateinit var adapter: UploadBodyAdapter
    private lateinit var tempDir: File

    override fun onCreateView() {
        this.tempDir = File(requireContext().cacheDir, "ATTACHMENT_TEMP")
        this.contentFiles = mutableListOf()
        this.launcher = registerLauncher(this)
        this.adapter = UploadBodyAdapter(requireContext(), handler!!, mutableListOf(UploadBody())).also {
            it.launcher = launcher
            it.contentFiles = contentFiles
        }
        b?.root?.adapter = this.adapter
        adapter.sync()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        // 清空临时目录
        tempDir.deleteRecursively()
    }

    override fun onActivityResult(result: ActivityResult) {
        if (result.resultCode != Activity.RESULT_OK) return
        val uri = result.data?.data ?: return
        val contentResolver = requireActivity().contentResolver
        // 文件信息
        val contentFile = ContentFile(uri, requireActivity())

        if (!AVAILABLE_EXT.any { it.equals(contentFile.ext, true) }) {
            toastLong("仅支持上传如下文件: ${AVAILABLE_EXT.joinToString(",")}")
            return
        }

        // 复制文件
        val dir = File(tempDir, UUID.randomUUID().toString()).also { it.mkdirs() }
        val filename = contentFile.originalName ?: UUID.randomUUID().toString().let { "$it.${contentFile.ext}" }
        val destFile = File(dir, filename).also { it.createNewFile() }
        contentResolver.openInputStream(uri)?.buffered()?.copyTo(destFile.outputStream())

        // 上传文件
        toast("开始上传: $filename")

        val builder = UploadBodyBuilder(uploadArgument.auth, uploadArgument.forumId, destFile)
            .description("upload at ${TimeUtils.SIMPLE_DATE_TIME_FORMATTER.format(ZonedDateTime.now())}")

        App.INSTANCE.ngaApi.postApi.attachUpload(uploadArgument.attachUrl, builder.build()).enqueue(object : Callback<UploadBody?> {
            override fun onResponse(call: Call<UploadBody?>, response: Response<UploadBody?>) {
                if (response.code()!=200) {
                    AlertDialogUtils.builder(requireContext(),"上传失败: ${response.code()}","请检查附件体积、图片宽高是否过大").show()
                    return
                }

                val uploadBody = response.body()!!

                if (uploadBody.error != null) {
                    toast("上传失败: ${uploadBody.errorCode}: ${uploadBody.error}")
                } else {
                    toast("上传成功: $filename")
                    contentFiles.add(contentFile)
                    adapter.pushData(response.body()!!)
                }
            }

            override fun onFailure(call: Call<UploadBody?>, t: Throwable) {
                toast("上传失败: $filename")
                t.printStackTrace()
            }
        })

    }

    override fun handleArguments(bundle: Bundle) {
        super.handleArguments(bundle)
        this.uploadArgument = parseBundle(bundle, UploadArgument::class.java.simpleName, UploadArgument::class.java)
    }


    companion object {
        /**
         * 允许上传的后缀名
         */
        private val AVAILABLE_EXT = listOf("jpg", "jpeg", "png", "gif", "mp3", "mp4", "zip")

        fun newInstance(uploadArgument: UploadArgument) =
            PostAttachmentUploadFragment().also { it.arguments = Bundle().also { b -> b.putParcelable(UploadArgument::class.java.simpleName, uploadArgument) } }
    }
}